#Load necessary libraries
library(plotly)
## Loading required package: ggplot2
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
#Define the 3D Function
# Formula given by :
  # (x^2 + (9/4)*y^2 + z^2 -1)^3 -x^2 - (9/200) * y^2*z^3 = 0
generate_3d_heart = function(n = 110000) { 
  #Initialize empty vectors for x, y, z
  x = numeric(n)
  y = numeric(n)
  z = numeric(n)
  
  #Generate points that satisfy the 3D heart equation
  count = 0
  while (count < n) {
    #Randomly sample points in a 3D bounding box
    x_test = runif(1, -1.5, 1.5)
    y_test = runif(1, -1.5, 1.5)
    z_test = runif(1, -1.5, 1.5)
    
    # Check if sampled data fall within heart space
    if ((x_test^2 + (9/4) * y_test^2 + z_test^2 - 1)^3 - x_test^2 * z_test^3 - (9/200) * y_test^2 * z_test^3 <= 0) {
    # Store the point
    count = count + 1
    x[count] = x_test
    y[count] = y_test
    z[count] = z_test
    }
  }
  
  # Density = distance from origin
  density = sqrt(x^2 + y^2 + z^2)
  data = data.frame(x = x, y = y, z = z, density = density)
  return(data)
}

#Generate heart data
hdata = generate_3d_heart()

# Plot using Plotly
figure  = plot_ly(x = ~hdata$x,
                  y = ~hdata$y,
                  z = ~hdata$z,
                  type = "scatter3d",
                  mode = "markers",
                  color = ~hdata$density,
                  marker = list(size = 1.5)) %>%
  layout(scene = list(xaxis = list(title="X"),
                      yaxis = list(title="Y"),
                      zaxis = list (title = "Z")),
         paper_bgcolor = "black",
         plot_bgcolor = "black")


figure